import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:icons_plus/icons_plus.dart';

import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:super_study_language_tools/panel/panel_help.dart';
import 'package:super_study_language_tools/panel/panel_user_info.dart';
import 'package:super_study_language_tools/tools/tools_common.dart';

import '../dao/dao_user_album_media_record.dart';
import '../model/model_srt_span.dart';
import '../model/model_user_album_media.dart';
import '../model/model_user_album_media_record.dart';
import '../panel/panel_dictionary.dart';
import '../panel/panel_user_word_list.dart';
import '../service/service_user_album_media_record.dart';
import '../tools/tools_subtitle.dart';
import '../widget/widget_number_input.dart';
import '../widget/widget_player_progress_div.dart';
import '../widget/widget_srt_info.dart';
import '../widget/widget_subtitle.dart';

class PagePlayer extends StatefulWidget {
  PagePlayer({super.key, required this.mode, required this.media});

  // 运行模式
  int mode = 0;

  // 媒体信息
  ModelUserAlbumMedia media;

  @override
  State<PagePlayer> createState() => _PagePlayerState();
}

class _PagePlayerState extends State<PagePlayer> with SingleTickerProviderStateMixin {
  // 播放器
  late final _player = Player();
  // 播放器控制器
  late final _videoController = VideoController(_player);

  // mp4路径
  String? _mp4Path;
  // mp3路径
  String? _mp3Path;

  // srt路径
  String? _srtPath1;
  String? _srtPath2;

  //-------------------------------------------控制
  // 播放时间
  var _playPosition = 0.obs;
  var _playPositionStr = "".obs;

  // 播放开关
  var _playOn = true.obs;

  // 是否复读
  var _repeatOn = true.obs;

  // 正在跳回
  bool _jumpingBack = false;

  // 是否跳过空白(无字幕部分)
  var _jumpBlank = false.obs;

  // 正在跳空
  bool _jumpingBlank = false;

  // 跳转定时器
  Timer? _jumpTimer = null;

  // 每播放一句后等待秒数
  int _repeatWaitTime = 1;

  // 上一次跳转时间
  DateTime? _lastJumpTime = DateTime.now();

  //-------------------------------------------遮盖
  // 显示遮住块(遮住默认字幕)
  var _showHideDiv = Rx<bool>(false); //false.obs;
  var _moveBarHeight = 10.0.obs;
  var _moveBarBottom = 20.0.obs;
  var _tmpMoveBarBottom = 0.0.obs;

  //-------------------------------------------字幕
  // 所有字幕列表
  List<ModelSrtSpan> _srts = [];
  List<ModelSrtSpan> _srts2 = [];

  // 是否显示字幕
  var _showSubtitle1 = false.obs;
  var _showSubtitle2 = false.obs;

  // 当前字幕
  var _curSubtitle1 = "test subtitle1".obs;
  String _curSubtitle2 = "test subtitle2";

  // 当前字幕索引
  var _curIndex = (-1).obs;

  // 最后一次对应的字幕索引
  int _lastIndex = -1;

  // 跳转字幕索引
  int _jumpToIndex = -1;

  //-------------------------------------------学习进度
  // 进度ok信息
  var _srtsOkMap = Rx<Map<int, int>>({});

  final ScrollController _scrollController = ScrollController();

  //-------------------------------------------用户输入
  // 键盘监听
  FocusNode _focusNode = FocusNode();

  // 当前要输入的单词列表
  List<String> _curSubtitleWords = [];

  // 用户输入的单词列表
  // List<String> _inputWords = [];
  final _inputWords = Rx<List<String>>([]);

  // 最近输入的内容
  var _inputLine = "".obs;

  // 正在输入的文字
  var _inputWord = "".obs;

  //--------------------------------------------显示右侧面板
  var _showRightPanel = false.obs;

  //--------------------------------------------显示字幕工具面板
  var _showSrtToolPanel = false.obs;

  TextEditingController? _srtTextController = TextEditingController();

  //
  var _tabController;
  late PanelDictionary _panelDictionary;
  late PanelUserWordList _panelUserWordList;
  late PanelUserInfo _panelUserInfo;
  // late PanelHelp _panelHelp;
  var _tabIndex = (-1).obs;
  //===================================================================

  //--------------------------------------------生命周期
  @override
  void initState() {
    super.initState();

    // 设定媒体路径
    print(widget.media);
    if (widget.media != null) {
      _mp4Path = widget.media.album!.filePath! + "/" + widget.media.fileName!;
      _srtPath1 = _mp4Path!.substring(0, _mp4Path!.lastIndexOf(".")) + ".srt";
    }

    // 读取字幕
    foo_readSrt().then((v) {
      setState(() {});
    });

    // 开始播放
    foo_play();

    // 监听视频播放状态
    _player.stream.position.listen(foo_positionListenHandle);

    //
    _tabController = TabController(length: 4, vsync: this);
    _tabController.addListener(() {
      _tabIndex.value = _tabController.index;
    });
    _panelDictionary = new PanelDictionary();
    _panelUserWordList = new PanelUserWordList();
    _panelUserInfo = new PanelUserInfo();
    // _panelHelp = new PanelHelp();
  }

  @override
  void dispose() {
    if (_jumpTimer != null) {
      _jumpTimer!.cancel();
    }
    _player.dispose();
    _scrollController.dispose();
    _tabController.dispose();
    super.dispose();
  }

//--------------------------------------------创建界面
  @override
  Widget build(BuildContext context) {
    FocusScope.of(context).requestFocus(_focusNode);
    FocusScope.of(context).autofocus(_focusNode);

    return Scaffold(
      appBar: AppBar(
        title: Text("学习${widget.media.fileName!}"),
        actions: [
          IconButton(
              onPressed: () {
                op("op_show_right_panel");
                _showRightPanel.value = !_showRightPanel.value;
                setState(() {});
              },
              icon: Icon(
                  _showRightPanel.value ? Bootstrap.layout_sidebar_reverse : Bootstrap.layout_sidebar_inset_reverse))
        ],
      ),
      body: Row(
        children: [buildLeftPanel(), buildRightPanel()],
      ),
    );
  }

  // 左侧
  buildLeftPanel() {
    return Expanded(
        child: Column(
      children: [
        buildMoviePanel(),
        buildSubtitlePanel(),
        buildToolBar(),
        buildProgressBar(),
        Obx(() => (_showSrtToolPanel.value ? buildSrtToolPanel() : buildInputPanel()))
      ],
    ));
  }

  // 右侧
  // buildRightPanel() {
  //   return Container(width: 300, child: Placeholder());
  // }

  var activeTextStyle = TextStyle(color: Colors.blueAccent);
  var normalTextStyle = TextStyle(color: Colors.black87);

  var _rightPanel;

  buildRightPanel() {
    // return Container(
    //   width: 30,
    //   child: Placeholder(),
    // );

    if (_rightPanel == null) {
      _rightPanel = Obx(() => Container(
            width: 380,
            child: Column(
              children: [
                TabBar(
                  tabs: [
                    Row(
                      children: [
                        // Icon(Icons.list_outlined),
                        Text(
                          "字幕",
                          style: _tabIndex.value == 0 ? activeTextStyle : normalTextStyle,
                        ),
                      ],
                    ),
                    Row(
                      children: [
                        // Icon(Icons.find_in_page_outlined),
                        Text(
                          "查单词",
                          style: _tabIndex.value == 1 ? activeTextStyle : normalTextStyle,
                        ),
                      ],
                    ),
                    Row(
                      children: [
                        // Icon(Icons.menu_book),
                        Text(
                          "单词本",
                          style: _tabController.index == 2 ? activeTextStyle : normalTextStyle,
                        ),
                      ],
                    ),
                    Row(
                      children: [
                        // Icon(Icons.list_outlined),
                        Text(
                          "我的",
                          style: _tabController.index == 3 ? activeTextStyle : normalTextStyle,
                        ),
                      ],
                    ),
                    // Row(
                    //   children: [
                    //     // Icon(Icons.list_outlined),
                    //     Text("帮助"),
                    //   ],
                    // ),
                  ],
                  controller: _tabController,
                ),
                Expanded(
                  child: TabBarView(
                    children: [
                      buildSrtsList(), _panelDictionary, _panelUserWordList,
                      _panelUserInfo,
                      // _panelHelp
                    ],
                    controller: _tabController,
                  ),
                )
              ],
            ),
          ));
    }

    return Obx(() => _showRightPanel.value
        ? _rightPanel
        : Container(
            width: 0,
          ));
    // Padding(
    //         padding: const EdgeInsets.all(2.0),
    //         child: Container(
    //             width: 35,
    //             child: Column(
    //               children: [
    //                 IconButton(
    //                     onPressed: () {
    //                       _showRightPanel.value = true;
    //                       _tabController.animateTo(0);
    //                       setState(() {});
    //                     },
    //                     icon: Icon(Icons.list_outlined)),
    //                 IconButton(
    //                     onPressed: () {
    //                       _showRightPanel.value = true;
    //                       _tabController.animateTo(1);
    //                       setState(() {});
    //                     },
    //                     icon: Icon(Icons.find_in_page_outlined)),
    //                 IconButton(
    //                     onPressed: () {
    //                       _showRightPanel.value = true;
    //                       _tabController.animateTo(2);
    //                       setState(() {});
    //                     },
    //                     icon: Icon(Icons.menu_book)),
    //               ],
    //             )),
    //       );
  }

  // 左1
  buildMoviePanel() {
    return Expanded(
        child: Stack(children: [
      Video(
        controller: _videoController,
        subtitleViewConfiguration: SubtitleViewConfiguration(visible: false), // 关闭内置字幕
      ),
      Obx(() => Positioned(
          // top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          child: Container(
            height: _showHideDiv.value
                ? ((_moveBarBottom.value + _moveBarHeight.value - _tmpMoveBarBottom.value) > 0
                    ? (_moveBarBottom.value + _moveBarHeight.value - _tmpMoveBarBottom.value)
                    : 0)
                : 0,
            color: Colors.green,
          ))),
      Obx(() => Positioned(
            // top: 0,
            left: 0,
            right: 0,
            bottom: (_moveBarBottom.value - _tmpMoveBarBottom.value > 0)
                ? (_moveBarBottom.value - _tmpMoveBarBottom.value)
                : 0,
            child: GestureDetector(
              onVerticalDragUpdate: (e) {
                print("onVerticalDragUpdate: (${e.localPosition.dy})");
                _tmpMoveBarBottom.value = e.localPosition.dy;
              },
              onVerticalDragEnd: (e) {
                print("onVerticalDragEnd: (${e.localPosition.dy})");
                // _moveBarBottom.value -= _tmpMoveBarBottom.value;
                _moveBarBottom.value -= e.localPosition.dy;
                _tmpMoveBarBottom.value = 0;
                if (_moveBarBottom.value < 0) {
                  _moveBarBottom.value = 0;
                }
              },
              child: MouseRegion(
                cursor: SystemMouseCursors.resizeUpDown,
                child: Obx(() => Container(
                      height: _showHideDiv.value ? _moveBarHeight.value : 0,
                      color: Colors.blue,
                    )),
              ),
            ),
          )),
    ]));
  }

  // 左2
  buildSubtitlePanel() {
    return Column(
      children: [
        Obx(() => WidgetSubtitle(
              height: 50,
              fontSize: 25,
              showSubtitle: _showSubtitle1.value,
              subtitle: _curSubtitle1.value,
              textColor: Colors.white,
              wrongTextColor: Colors.white,
              backgroundColor: Colors.black,
            ))
      ],
    );

    // List<Widget> l = [];
    // if (_showSubtitle1.value! && _srtPath1 != null) {
    //   l.add(
    //     Obx(()=>WidgetSubtitle(
    //       height: 50,
    //       fontSize: 25,
    //       showSubtitle: _showSubtitle1.value,
    //       subtitle: _curSubtitle1.value,
    //       textColor: Colors.white,
    //       wrongTextColor: Colors.white,
    //       backgroundColor: Colors.black,
    //     ))
    //       );
    // }
    // if (_showSubtitle2! && _srtPath2 != null) {
    //   l.add(WidgetSubtitle(
    //     height: 50,
    //     fontSize: 25,
    //     showSubtitle: _showSubtitle2,
    //     subtitle: _curSubtitle2,
    //     textColor: Colors.white,
    //     wrongTextColor: Colors.white,
    //     backgroundColor: Colors.black,
    //   ));
    // }
    // return Column(
    //   children: l,
    // );
  }

  // 左3 工具栏面板
  buildToolBar() {
    bool isDesktop = ToolsCommon.isDesktop(context);
    return ToolsCommon.isDesktop(context) ? buildDesktopToolBar() : buildMobileToolBar();
  }

  buildMobileToolBar() {
    return Column(
      children: [
        Container(
            height: 40,
            child: Row(
              mainAxisAlignment:
                  ToolsCommon.isDesktop(context) ? MainAxisAlignment.start : MainAxisAlignment.spaceAround,
              children: [
                // 播放进度时间
                SizedBox(
                    width: 75,
                    // height: 40,
                    child: Obx(() => Text("${_playPositionStr.value}", textAlign: TextAlign.center))),
                // 播放暂停按钮
                SizedBox(
                  width: 32,
                  height: 40,
                  child: Obx(
                    () => IconButton(
                      onPressed: () {
                        op("op_play_or_pause");
                      },
                      icon: _playOn.value ? Icon(Icons.pause) : Icon(Icons.play_arrow),
                      tooltip: _playOn.value ? "暂停" : "播放",
                      padding: EdgeInsets.zero,
                      constraints: BoxConstraints.tightForFinite(width: 32.0),
                    ),
                  ),
                ),
                SizedBox(
                  width: 32,
                  child: IconButton(
                    onPressed: () {
                      op("op_prev_srt");
                    },
                    icon: Icon(Icons.skip_previous),
                    tooltip: "前一句",
                    padding: EdgeInsets.zero,
                    constraints: BoxConstraints.tightForFinite(width: 32.0),
                  ),
                ),
                SizedBox(
                  width: 32,
                  child: IconButton(
                    onPressed: () {
                      op("op_next_srt");
                    },
                    icon: Icon(Icons.skip_next),
                    tooltip: "后一句",
                    padding: EdgeInsets.zero,
                    constraints: BoxConstraints.tightForFinite(width: 32.0),
                  ),
                ),
                SizedBox(
                  width: 80,
                  child: Obx(() => Text(
                        _srts == null ? "" : "${_srtsOkMap.value.keys.length}/${_srts!.length}",
                        textAlign: TextAlign.center,
                      )),
                ),
              ],
            )),
        Container(
          height: 40,
          child: Row(
            mainAxisAlignment: ToolsCommon.isDesktop(context) ? MainAxisAlignment.start : MainAxisAlignment.spaceAround,
            children: [
              Obx(() => SizedBox(
                        width: 32,
                        child: IconButton(
                          onPressed: () {
                            _showSubtitle1.value = !_showSubtitle1.value;
                          },
                          icon: Icon(_showSubtitle1.value ? Icons.subtitles_off : Icons.subtitles),
                          padding: EdgeInsets.zero,
                          constraints: BoxConstraints.tightForFinite(width: 32.0),
                          tooltip: _showSubtitle1.value ? "隐藏字幕" : "显示字幕",
                        ),
                      )
                  // Checkbox(
                  // activeColor: Colors.green,
                  // value: _showSubtitle1.value,
                  // onChanged: (v) {
                  //   _showSubtitle1.value = v!;
                  //   print("_showSubtitle1.value:${_showSubtitle1.value}");
                  //   op("op_switch_sub1");
                  // })
                  ),
              // SizedBox(
              //   width: 90,
              //   child: Obx(()=>TextButton(
              //     child: Text(_showSubtitle1.value?"隐藏字幕":"显示字幕"),onPressed: (){_showSubtitle1.value = !_showSubtitle1.value;}),),
              // ),
              //)),
              // Checkbox(
              //     value: _repeatOn,
              //     onChanged: (v) {
              //       setState(() {
              //         _repeatOn = v;
              //         foo_cancelJump();
              //       });
              //     }),
              SizedBox(
                width: 25,
                child: IconButton(
                  onPressed: () {
                    _repeatOn.value = !_repeatOn.value;
                    Get.snackbar("信息", _repeatOn.value ? "单句循环已开启" : "单句循环已关闭", duration: Duration(seconds: 1));
                  },
                  icon: Obx(() => Icon(_repeatOn.value ? Icons.repeat_one : Icons.repeat)),
                  tooltip: !_repeatOn.value ? "单句循环" : "取消单句循环",
                  padding: EdgeInsets.zero,
                  constraints: BoxConstraints.tightForFinite(width: 32.0),
                ),
              ),
              // const Text("复读"),
              // const Text("  间隔:"),
              // Material(
              //     child: WidgetNumberInput(
              //   onValueChanged: op_repeatWaitTimeChange,
              //   num: _repeatWaitTime,
              // )),
              // Text("秒"),
              // Checkbox(
              //     value: _showHideDiv.value,
              //     onChanged: (v) {
              //       _showHideDiv.value = !_showHideDiv.value;
              //     }),
              // Text("遮盖字幕"),
              SizedBox(
                width: 25,
                child: IconButton(
                  onPressed: () {
                    _showHideDiv.value = !_showHideDiv.value;
                  },
                  icon: Obx(() => Icon(_showHideDiv.value ? Icons.inbox_sharp : Icons.check_box_outline_blank_sharp)),
                  tooltip: _showHideDiv.value ? "显示遮盖块" : "隐藏遮盖块",
                  padding: EdgeInsets.zero,
                  constraints: BoxConstraints.tightForFinite(width: 32.0),
                ),
              ),
              // Obx(() => Checkbox(
              //     value: _jumpBlank.value,
              //     onChanged: (v) {
              //       _jumpBlank.value = v!;
              //     })),
              // const Text("跳空"),
              SizedBox(
                width: 25,
                child: Obx(() => IconButton(
                      onPressed: () {
                        _jumpBlank.value = !_jumpBlank.value;
                      },
                      icon: Icon(_jumpBlank.value ? Clarity.fast_forward_line : Clarity.fast_forward_solid),
                      padding: EdgeInsets.zero,
                      constraints: BoxConstraints.tightForFinite(width: 32.0),
                      tooltip: _jumpBlank.value ? "不跳过无字幕部分" : "自动跳过无字幕部分",
                    )),
              ),
              SizedBox(
                  width: 32,
                  child: IconButton(
                      onPressed: () {
                        op("op_ignore_srt");
                      },
                      icon: Icon(FontAwesome.text_slash_solid),
                      padding: EdgeInsets.zero,
                      constraints: BoxConstraints.tightForFinite(width: 32.0),
                      tooltip: "忽略当前句子")),
              // TextButton(
              //     onPressed: () {
              //       print("忽略");
              //       op("op_ignore_srt");
              //     },
              //     child: Text("忽略这句")),
              // Checkbox(
              //     value: _showSrtToolPanel,
              //     onChanged: (v) {
              //       setState(() {
              //         _showSrtToolPanel = v!;
              //       });
              //     }),
              // Text(_showSrtToolPanel ? "字幕工具" : "字幕工具"),
              SizedBox(
                  width: 32,
                  child: Obx(() => IconButton(
                        onPressed: () {
                          _showSrtToolPanel.value = !_showSrtToolPanel.value;
                        },
                        icon: Icon(_showSrtToolPanel.value ? FontAwesome.hammer_solid : FontAwesome.toolbox_solid),
                        padding: EdgeInsets.zero,
                        constraints: BoxConstraints.tightForFinite(width: 32.0),
                        tooltip: _showSrtToolPanel.value ? "关闭字幕工具箱" : "显示字幕工具箱",
                      ))),
              SizedBox(
                width: 30,
                child: IconButton(
                  onPressed: () {},
                  icon: Icon(Icons.settings),
                  padding: EdgeInsets.zero,
                  constraints: BoxConstraints.tightForFinite(width: 32.0),
                  tooltip: "其他设置",
                ),
              )
            ],
          ),
        ),
      ],
    );
  }

  buildDesktopToolBar() {
    return Container(
      height: 40,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // 播放进度时间
          SizedBox(
              width: 75,
              // height: 40,
              child: Obx(() => Text("${_playPositionStr.value}", textAlign: TextAlign.center))),
          // 播放暂停按钮
          SizedBox(
            width: 32,
            height: 40,
            child: Obx(
              () => IconButton(
                onPressed: () {
                  op("op_play_or_pause");
                },
                icon: _playOn.value ? Icon(Icons.pause) : Icon(Icons.play_arrow),
                tooltip: _playOn.value ? "暂停" : "播放",
                padding: EdgeInsets.zero,
                constraints: BoxConstraints.tightForFinite(width: 32.0),
              ),
            ),
          ),
          SizedBox(
            width: 32,
            child: IconButton(
              onPressed: () {
                op("op_prev_srt");
              },
              icon: Icon(Icons.skip_previous),
              tooltip: "前一句",
              padding: EdgeInsets.zero,
              constraints: BoxConstraints.tightForFinite(width: 32.0),
            ),
          ),
          SizedBox(
            width: 32,
            child: IconButton(
              onPressed: () {
                op("op_next_srt");
              },
              icon: Icon(Icons.skip_next),
              tooltip: "后一句",
              padding: EdgeInsets.zero,
              constraints: BoxConstraints.tightForFinite(width: 32.0),
            ),
          ),
          SizedBox(
            width: 80,
            child: Obx(() => Text(
                  _srts == null ? "" : "${_srtsOkMap.value.keys.length}/${_srts!.length}",
                  textAlign: TextAlign.center,
                )),
          ),
          Obx(() => SizedBox(
                    width: 32,
                    child: IconButton(
                      onPressed: () {
                        _showSubtitle1.value = !_showSubtitle1.value;
                      },
                      icon: Icon(_showSubtitle1.value ? Icons.subtitles_off : Icons.subtitles),
                      padding: EdgeInsets.zero,
                      constraints: BoxConstraints.tightForFinite(width: 32.0),
                      tooltip: _showSubtitle1.value ? "隐藏字幕" : "显示字幕",
                    ),
                  )
              // Checkbox(
              // activeColor: Colors.green,
              // value: _showSubtitle1.value,
              // onChanged: (v) {
              //   _showSubtitle1.value = v!;
              //   print("_showSubtitle1.value:${_showSubtitle1.value}");
              //   op("op_switch_sub1");
              // })
              ),
          // SizedBox(
          //   width: 90,
          //   child: Obx(()=>TextButton(
          //     child: Text(_showSubtitle1.value?"隐藏字幕":"显示字幕"),onPressed: (){_showSubtitle1.value = !_showSubtitle1.value;}),),
          // ),
          //)),
          // Checkbox(
          //     value: _repeatOn,
          //     onChanged: (v) {
          //       setState(() {
          //         _repeatOn = v;
          //         foo_cancelJump();
          //       });
          //     }),
          SizedBox(
            width: 25,
            child: IconButton(
              onPressed: () {
                _repeatOn.value = !_repeatOn.value;
                Get.snackbar("信息", _repeatOn.value ? "单句循环已开启" : "单句循环已关闭", duration: Duration(seconds: 1));
              },
              icon: Obx(() => Icon(_repeatOn.value ? Icons.repeat_one : Icons.repeat)),
              tooltip: !_repeatOn.value ? "单句循环" : "取消单句循环",
              padding: EdgeInsets.zero,
              constraints: BoxConstraints.tightForFinite(width: 32.0),
            ),
          ),
          // const Text("复读"),
          // const Text("  间隔:"),
          // Material(
          //     child: WidgetNumberInput(
          //   onValueChanged: op_repeatWaitTimeChange,
          //   num: _repeatWaitTime,
          // )),
          // Text("秒"),
          // Checkbox(
          //     value: _showHideDiv.value,
          //     onChanged: (v) {
          //       _showHideDiv.value = !_showHideDiv.value;
          //     }),
          // Text("遮盖字幕"),
          SizedBox(
            width: 25,
            child: IconButton(
              onPressed: () {
                _showHideDiv.value = !_showHideDiv.value;
              },
              icon: Obx(() => Icon(_showHideDiv.value ? Icons.inbox_sharp : Icons.check_box_outline_blank_sharp)),
              tooltip: _showHideDiv.value ? "显示遮盖块" : "隐藏遮盖块",
              padding: EdgeInsets.zero,
              constraints: BoxConstraints.tightForFinite(width: 32.0),
            ),
          ),
          // Obx(() => Checkbox(
          //     value: _jumpBlank.value,
          //     onChanged: (v) {
          //       _jumpBlank.value = v!;
          //     })),
          // const Text("跳空"),
          SizedBox(
            width: 25,
            child: Obx(() => IconButton(
                  onPressed: () {
                    _jumpBlank.value = !_jumpBlank.value;
                  },
                  icon: Icon(_jumpBlank.value ? Clarity.fast_forward_line : Clarity.fast_forward_solid),
                  padding: EdgeInsets.zero,
                  constraints: BoxConstraints.tightForFinite(width: 32.0),
                  tooltip: _jumpBlank.value ? "不跳过无字幕部分" : "自动跳过无字幕部分",
                )),
          ),
          SizedBox(
              width: 32,
              child: IconButton(
                  onPressed: () {
                    op("op_ignore_srt");
                  },
                  icon: Icon(FontAwesome.text_slash_solid),
                  padding: EdgeInsets.zero,
                  constraints: BoxConstraints.tightForFinite(width: 32.0),
                  tooltip: "忽略当前句子")),
          // TextButton(
          //     onPressed: () {
          //       print("忽略");
          //       op("op_ignore_srt");
          //     },
          //     child: Text("忽略这句")),
          // Checkbox(
          //     value: _showSrtToolPanel,
          //     onChanged: (v) {
          //       setState(() {
          //         _showSrtToolPanel = v!;
          //       });
          //     }),
          // Text(_showSrtToolPanel ? "字幕工具" : "字幕工具"),
          SizedBox(
              width: 32,
              child: Obx(() => IconButton(
                    onPressed: () {
                      _showSrtToolPanel.value = !_showSrtToolPanel.value;
                    },
                    icon: Icon(_showSrtToolPanel.value ? FontAwesome.toolbox_solid : FontAwesome.hammer_solid),
                    padding: EdgeInsets.zero,
                    constraints: BoxConstraints.tightForFinite(width: 32.0),
                    tooltip: _showSrtToolPanel.value ? "关闭字幕工具箱" : "显示字幕工具箱",
                  ))),
          SizedBox(
            width: 30,
            child: IconButton(
              onPressed: () {},
              icon: Icon(Icons.settings),
              padding: EdgeInsets.zero,
              constraints: BoxConstraints.tightForFinite(width: 32.0),
              tooltip: "其他设置",
            ),
          )
        ],
      ),
    );
  }

  // 左4 进度条面板
  buildProgressBar() {
    return Container(
      width: double.infinity,
      // width: 300,
      height: (_srts == null || _srts.length == 0) ? 0 : 30,
      decoration: BoxDecoration(color: Colors.grey),
      child: (_srts == null || _srts.length == 0)
          ? null
          : (_srts.length < 20
              ? Flex(
                  direction: Axis.horizontal,
                  children: buildProgressBarDivs(),
                )
              : buildProgressBarListView()),
    );
  }

  // 左4.1 小于20进度条
  buildProgressBarDivs() {
    List<Widget> list = [];
    if (_srts == null) {
      Widget w = Expanded(
        flex: 1,
        child: Container(
          height: 28.0,
          color: Colors.white10,
        ),
      );
      list.add(w);
    } else {
      for (int i = 0; i < _srts!.length; i++) {
        Widget w = Expanded(
          flex: 1,
          child: Obx(() => WidgetPlayerProgressDiv(
              srtsOkMap: _srtsOkMap.value,
              i: i,
              curIndex: _curIndex.value,
              onTap: () {
                op_jumpTo(i);
              })),
        );
        list.add(w);
      }
    }
    return list;
  }

  // 左4.2 大于20进度条
  buildProgressBarListView() {
    // print("buildProgressBarListView()");
    return Container(
      child: Row(
        children: [
          SizedBox(
            width: 50,
            height: 50,
            child: IconButton(
              icon: Icon(Icons.arrow_back),
              onPressed: () {
                op("op_scroll_left");
              },
            ),
          ),
          Expanded(
            child: SizedBox(
              height: 50,
              child: ListView.builder(
                  controller: _scrollController,
                  scrollDirection: Axis.horizontal,
                  itemCount: _srts.length,
                  itemBuilder: (BuildContext context, int i) {
                    return Obx(() => WidgetPlayerProgressDiv(
                        srtsOkMap: _srtsOkMap.value,
                        i: i,
                        curIndex: _curIndex.value,
                        onTap: () {
                          op_jumpTo(i);
                        }));
                  }),
            ),
          ),
          SizedBox(
            width: 50,
            height: 50,
            child: IconButton(
              icon: Icon(Icons.arrow_forward),
              onPressed: () {
                op("op_scroll_right");
              },
            ),
          ),
        ],
      ),
    );
  }

  // 左5
  buildSrtToolPanel() {
    // if (_curIndex.value == -1) _curIndex.value = 0;
    ModelSrtSpan? span;
    if (_curIndex.value != -1) {
      span = _srts[_curIndex.value];
    }
    _srtTextController = TextEditingController(text: span == null ? "" : span!.content);
    _srtTextController!.addListener(op_changeSrt);
    return Column(
      children: [
        Row(children: [
          Text("开始时间: ${span == null ? "" : ToolsSubtitle.toHHmmss(span.startTime)}"),
          Text("结束时间:${span == null ? "" : ToolsSubtitle.toHHmmss(span.endTime)}"),
          TextButton(
              onPressed: () {
                op("srt_del_cur");
              },
              child: Text("删除")),
          TextButton(
              onPressed: () {
                op("srt_del_after");
              },
              child: Text("删除后面")),
          TextButton(
              onPressed: () {
                op("save_srts");
              },
              child: Text("保存")),
          TextButton(
              onPressed: () {
                op("srt_combine_prev");
              },
              child: Text("与前一段合并")),
          TextButton(
              onPressed: () {
                op("srt_combine_next");
              },
              child: Text("与后一段合并"))
        ]),
        Row(
          children: [
            Text("开始时间修改:"),
            TextButton(
                onPressed: () {
                  op("start_sub_1000ms");
                },
                child: Text("-1s")),
            TextButton(
                onPressed: () {
                  op("start_sub_100ms");
                },
                child: Text("-0.1s")),
            TextButton(
                onPressed: () {
                  op("start_sub_10ms");
                },
                child: Text("-0.01s")),
            TextButton(
                onPressed: () {
                  op("start_add_10ms");
                },
                child: Text("+0.01s")),
            TextButton(
                onPressed: () {
                  op("start_add_100ms");
                },
                child: Text("+0.1s")),
            TextButton(
                onPressed: () {
                  op("start_add_1000ms");
                },
                child: Text("+1s")),
            Text("结束时间修改:"),
            TextButton(
                onPressed: () {
                  op("end_sub_1000ms");
                },
                child: Text("-1s")),
            TextButton(
                onPressed: () {
                  op("end_sub_100ms");
                },
                child: Text("-0.1s")),
            TextButton(
                onPressed: () {
                  op("end_sub_10ms");
                },
                child: Text("-0.01s")),
            TextButton(
                onPressed: () {
                  op("end_add_10ms");
                },
                child: Text("+0.01s")),
            TextButton(
                onPressed: () {
                  op("end_add_100ms");
                },
                child: Text("+0.1s")),
            TextButton(
                onPressed: () {
                  op("end_add_1000ms");
                },
                child: Text("+1s")),
          ],
        ),
        Row(
          children: [
            Text("整体修改:"),
            TextButton(
                onPressed: () {
                  op("all_sub_1000ms");
                },
                child: Text("-1s")),
            TextButton(
                onPressed: () {
                  op("all_sub_100ms");
                },
                child: Text("-0.1s")),
            TextButton(
                onPressed: () {
                  op("all_sub_10ms");
                },
                child: Text("-0.01s")),
            TextButton(
                onPressed: () {
                  op("all_add_10ms");
                },
                child: Text("+0.01s")),
            TextButton(
                onPressed: () {
                  op("all_add_100ms");
                },
                child: Text("+0.1s")),
            TextButton(
                onPressed: () {
                  op("all_add_1000ms");
                },
                child: Text("+1s")),
          ],
        ),
        Row(
          children: [
            Text("字幕内容:"),
            Container(
              width: 500,
              child: TextField(
                autofocus: true,
                controller: _srtTextController,
              ),
            ),
            TextButton(
                onPressed: () {
                  print("修改");
                  op("srt_modify_content");
                },
                child: Text("修改"))
          ],
        )
      ],
    );
  }

  // 左6
  buildInputPanel() {
    // TargetPlatform platform = Theme.of(context).platform;
    // print("平台:" + platform.toString());

    return Obx(() => Container(
          height: ToolsCommon.isDesktop(context) ? 150 : 300,
          child: Column(
            children: [
              WidgetSubtitle(
                height: 50,
                fontSize: 25,
                showSubtitle: true,
                subtitle: _curSubtitle1.value,
                textColor: Colors.white,
                inputWords: _inputWords.value,
                // 和背景色一样
                wrongTextColor: Colors.deepPurpleAccent,
                backgroundColor: Colors.deepPurpleAccent,
                undLineColor: Colors.white,
                showUnderLine: true,
              ),
              Container(
                decoration: BoxDecoration(color: Colors.lightBlueAccent),
                width: double.infinity,
                alignment: Alignment.center,
                height: 50,
                child: Text(
                  _inputLine.value,
                  style: TextStyle(fontSize: 36, color: Colors.white, decoration: TextDecoration.none),
                ),
              ),
              buildInputBar(),
              ToolsCommon.isDesktop(context)
                  ? Container(
                      height: 0,
                    )
                  : buildKeyBoard(),
            ],
          ),
        ));
  }

  buildButton(String c) {
    return SizedBox(
        width: 40,
        height: 50,
        child: TextButton(
            onPressed: () {
              _inputWord.value += c;
            },
            child: Text(c)));
  }

  buildKeyBoard() {
    return Container(
      height: 150,
      child: Column(
        children: [
          Row(
            children: [
              buildButton("q"),
              buildButton("w"),
              buildButton("e"),
              buildButton("r"),
              buildButton("t"),
              buildButton("y"),
              buildButton("u"),
              buildButton("i"),
              buildButton("o"),
              buildButton("p"),
            ],
          ),
          Row(
            children: [
              buildButton("a"),
              buildButton("s"),
              buildButton("d"),
              buildButton("f"),
              buildButton("g"),
              buildButton("h"),
              buildButton("j"),
              buildButton("k"),
              buildButton("l"),
              IconButton(
                  onPressed: () {
                    if (_inputWord.value.length == 1) {
                      _inputWord.value = "";
                    } else if (_inputWord.value.length == 0) {
                      // _inputWord.value = "";
                    } else {
                      _inputWord.value = _inputWord.value.substring(0, _inputWord.value.length - 1);
                    }
                  },
                  icon: Icon(Icons.backspace_sharp))
            ],
          ),
          Row(
            children: [
              SizedBox(width: 40, child: IconButton(onPressed: () {}, icon: Icon(Icons.keyboard_voice))),
              buildButton("z"),
              buildButton("x"),
              buildButton("c"),
              buildButton("v"),
              buildButton("b"),
              buildButton("n"),
              buildButton("m"),
              SizedBox(
                  width: 80,
                  child: IconButton(
                      onPressed: () {
                        _inputLine.value = _inputWord.value.trim();
                        _inputWord.value = "";
                        foo_checkInputSubtitle();
                      },
                      icon: Icon(Icons.keyboard_return_outlined)))
            ],
          ),
        ],
      ),
    );
  }

  buildInputBar() {
    // TargetPlatform platform = Theme.of(context).platform;
    // print("平台:" + platform.toString());
    // if (TargetPlatform.android == platform || TargetPlatform.iOS == platform) {
    //   return Container(
    //       decoration: BoxDecoration(color: Colors.red),
    //       width: double.infinity,
    //       alignment: Alignment.center,
    //       height: 50,
    //       child:
    //       TextField(
    //         autofocus: true,
    //         // controller: _srtTextController,
    //           keyboardType:TextInputType.text
    //       ),
    //   );
    // } else
    {
      return KeyboardListener(
        focusNode: _focusNode,
        autofocus: true, // 要开启自动焦点
        onKeyEvent: (KeyEvent event) {
          print("focusNode2:${event},${event.runtimeType}");

          // event.runtimeType == KeyUpEvent
          // event.runtimeType == KeyRepeatEvent
          print("event.character:${event.character}");
          print("event.logicalKey.keyLabel:${event.logicalKey.keyLabel}");
          print("event.logicalKey.debugName:${event.physicalKey.debugName}");
          if (event.runtimeType == KeyUpEvent) {
            if (event.logicalKey.keyLabel == "Enter" || event.physicalKey.debugName == "Space") {
              _inputLine.value = _inputWord.value.trim();
              _inputWord.value = "";
              foo_checkInputSubtitle();
            }
          } else if (event.runtimeType == KeyDownEvent) {
            if (event.logicalKey.keyLabel == "Arrow Up") {
              print("向上键");

              _inputWord = _inputLine;
            } else if (event.logicalKey.keyLabel == "Backspace") {
              if (_inputWord.value.length > 0) {
                print(_inputWord);
                if (_inputWord.value.length == 1) {
                  _inputWord.value = "";
                } else {
                  _inputWord.value = _inputWord.value.substring(0, _inputWord.value.length - 1);
                }
                print(_inputWord);
              }
            } else if (event.character != null) {
              _inputWord.value += event.character!;
            }
          }
        },
        child: Container(
          decoration: BoxDecoration(color: Colors.green),
          width: double.infinity,
          alignment: Alignment.center,
          height: 50,
          child: Text(
            _inputWord.value,
            style: TextStyle(fontSize: 36, color: Colors.white, decoration: TextDecoration.none),
          ),
        ),
      );
    }
  }

  // 右1
  buildSrtsList() {
    return Padding(
      padding: const EdgeInsets.all(0.0),
      child: Container(
          width: 300,
          // color: Colors.lightBlueAccent,
          child: ListView.separated(
              itemCount: _srts.length,
              // itemExtent: 80.0, //强制高度为50.0
              itemBuilder: (BuildContext context, int index) {
                ModelSrtSpan s = _srts[index];
                return WidgetSrtInfo(
                    srtSpan: s,
                    onPressed: (tmpI) {
                      print("${tmpI}");
                      op_jumpTo(tmpI - 1);
                    });
              },
              separatorBuilder: (context, index) {
                return Divider(
                  height: 5,
                );
              })),
    );
  }

  //=================================================================== 操作

  op(String opStr, [data]) {
    print(opStr);
    switch (opStr) {
      case "op_play_or_pause":
        print("播放或暂停");
        _playOn.value = !_playOn.value;
        if (_playOn.value) {
          _player.play();
        } else {
          _player.pause();
        }
        setState(() {});
        break;
      case "op_prev_srt":
        op_prevSrt();
        break;
      case "op_next_srt":
        op_nextSrt();
        break;
      case "op_jump_to":
        op_jumpTo(data);
        break;

      case "op_scroll_left":
        op_scrollLeft();
        break;
      case "op_scroll_right":
        op_scrollRight();
        break;

      case "op_switch_sub1":
        if (_showSubtitle1.value && !_showSrtToolPanel.value) {
          op_saveWrongSentence();
        }
        break;
      case "op_ignore_srt":
        op_ignoreSrt();
        break;

      case "start_sub_1000ms":
        // saveSrts();
        if (_srts[_curIndex.value].startTime > 1000) {
          _srts[_curIndex.value].startTime -= 1000;
          if (_curIndex >= 1 && (_srts[_curIndex.value].startTime < _srts[_curIndex.value - 1].endTime)) {
            _srts[_curIndex.value - 1].endTime = _srts[_curIndex.value].startTime - ToolsSubtitle.SRT_MIN_INTERVAL;
          }
        }
        setState(() {});
        break;
      case "start_sub_100ms":
        if (_srts[_curIndex.value].startTime > 100) {
          _srts[_curIndex.value].startTime -= 100;
          if (_curIndex >= 1 && (_srts[_curIndex.value].startTime < _srts[_curIndex.value - 1].endTime)) {
            _srts[_curIndex.value - 1].endTime = _srts[_curIndex.value].startTime - ToolsSubtitle.SRT_MIN_INTERVAL;
          }
        }
        setState(() {});
        break;
      case "start_sub_10ms":
        if (_srts[_curIndex.value].startTime > 10) {
          _srts[_curIndex.value].startTime -= 10;
          if (_curIndex >= 1 && (_srts[_curIndex.value].startTime < _srts[_curIndex.value - 1].endTime)) {
            _srts[_curIndex.value - 1].endTime = _srts[_curIndex.value].startTime - ToolsSubtitle.SRT_MIN_INTERVAL;
          }
        }
        setState(() {});
        break;
      case "start_add_10ms":
        if (_srts[_curIndex.value].startTime + 10 < _srts[_curIndex.value].endTime) {
          _srts[_curIndex.value].startTime += 10;
        }
        setState(() {});
        break;
      case "start_add_100ms":
        if (_srts[_curIndex.value].startTime + 100 < _srts[_curIndex.value].endTime) {
          _srts[_curIndex.value].startTime += 100;
        }
        setState(() {});
        break;
      case "start_add_1000ms":
        if (_srts[_curIndex.value].startTime + 1000 < _srts[_curIndex.value].endTime) {
          _srts[_curIndex.value].startTime += 1000;
        }
        setState(() {});
        break;
      case "end_sub_1000ms":
        if (_srts[_curIndex.value].endTime - 1000 > _srts[_curIndex.value].startTime) {
          _srts[_curIndex.value].endTime += 1000;
        }
        setState(() {});
        break;
      case "end_sub_100ms":
        if (_srts[_curIndex.value].endTime - 100 > _srts[_curIndex.value].startTime) {
          _srts[_curIndex.value].endTime += 100;
        }
        setState(() {});
        break;
      case "end_sub_10ms":
        if (_srts[_curIndex.value].endTime - 10 > _srts[_curIndex.value].startTime) {
          _srts[_curIndex.value].endTime += 10;
        }
        setState(() {});
        break;
      case "end_add_10ms":
        _srts[_curIndex.value].endTime += 10;

        if (_curIndex < _srts.length - 1 &&
            (_srts[_curIndex.value].endTime + 10 > _srts[_curIndex.value + 1].startTime)) {
          _srts[_curIndex.value + 1].startTime = _srts[_curIndex.value].endTime + ToolsSubtitle.SRT_MIN_INTERVAL;
        }
        setState(() {});
        break;
      case "end_add_100ms":
        _srts[_curIndex.value].endTime += 100;

        if (_curIndex < _srts.length - 1 &&
            (_srts[_curIndex.value].endTime + 10 > _srts[_curIndex.value + 1].startTime)) {
          _srts[_curIndex.value + 1].startTime = _srts[_curIndex.value].endTime + ToolsSubtitle.SRT_MIN_INTERVAL;
        }
        setState(() {});
        break;
      case "end_add_1000ms":
        _srts[_curIndex.value].endTime += 100;

        if (_curIndex < _srts.length - 1 &&
            (_srts[_curIndex.value].endTime + 10 > _srts[_curIndex.value + 1].startTime)) {
          _srts[_curIndex.value + 1].startTime = _srts[_curIndex.value].endTime + ToolsSubtitle.SRT_MIN_INTERVAL;
        }
        setState(() {});
        break;
      case "all_sub_1000ms":
        for (int i = 0; i < _srts.length; i++) {
          _srts[i].startTime -= 1000;
          _srts[i].endTime -= 1000;
        }
        setState(() {});
        break;
      case "all_sub_100ms":
        for (int i = 0; i < _srts.length; i++) {
          _srts[i].startTime -= 100;
          _srts[i].endTime -= 100;
        }
        setState(() {});

        break;
      case "all_sub_10ms":
        for (int i = 0; i < _srts.length; i++) {
          _srts[i].startTime -= 10;
          _srts[i].endTime -= 10;
        }
        setState(() {});
        break;
      case "all_add_10ms":
        for (int i = 0; i < _srts.length; i++) {
          _srts[i].startTime += 10;
          _srts[i].endTime += 10;
        }
        setState(() {});
        break;
      case "all_add_100ms":
        for (int i = 0; i < _srts.length; i++) {
          _srts[i].startTime += 100;
          _srts[i].endTime += 100;
        }
        setState(() {});
        break;
      case "all_add_1000ms":
        for (int i = 0; i < _srts.length; i++) {
          _srts[i].startTime += 1000;
          _srts[i].endTime += 1000;
        }
        setState(() {});
        break;
      case "save_srts":
        ToolsSubtitle.saveSrts(_srts, _srtPath1!);
        break;
      case "srt_del_cur":
        // for(int i=_curIndex;i<_srts.length;i++)
        //   {
        //               }
        _srts.removeAt(_curIndex.value);

        setState(() {});
        break;
      case "srt_del_after":
        _srts.removeRange(_curIndex.value + 1, _srts.length);
        setState(() {});
        break;
      case "srt_combine_prev":
        if (_curIndex > 1) {
          _srts[_curIndex.value - 1].endTime = _srts[_curIndex.value].endTime;
          _srts[_curIndex.value - 1].content += " " + _srts[_curIndex.value].content;
          _srts.removeAt(_curIndex.value);
        }
        setState(() {});
        break;
      case "srt_combine_next":
        if (_curIndex + 1 < _srts.length) {
          _srts[_curIndex.value].endTime = _srts[_curIndex.value + 1].endTime;
          _srts[_curIndex.value].content += " " + _srts[_curIndex.value + 1].content;
          _srts.removeAt(_curIndex.value + 1);
        }
        setState(() {});
        break;
      case "srt_modify_content":
        _srts[_curIndex.value].content = _srtTextController!.text;
        setState(() {});
        break;
    }
  }

  // 修改等待时间
  op_repeatWaitTimeChange(int t) {
    print("数字改变:${t}");
    this._repeatWaitTime = t;
  }

  op_prevSrt() {
    print("op_prevSrt()前一句");
    if (_srts == null) return;

    foo_cancelJump();

    print("curIndex = ${_curIndex.value}");
    int jumpIndex = -1;
    if (_curIndex.value > 0) {
      jumpIndex = _curIndex.value - 1;
    } else if (_curIndex.value == 0) {
      jumpIndex = 0;
    } else {
      if (_lastIndex > -1) {
        jumpIndex = _lastIndex;
      } else {
        jumpIndex = 0;
      }
    }
    if (jumpIndex != -1) {
      _player.seek(Duration(milliseconds: _srts![jumpIndex].startTime));
      _lastJumpTime = DateTime.now();
      // _showSubtitle1.value = false;
      _player.play();
    }
  }

  // 后一句
  op_nextSrt() {
    print("后一句");
    if (_srts == null) return;
    // 停止自动跳转
    _jumpingBack = false;
    if (_jumpTimer != null && _jumpTimer!.isActive) {
      _jumpTimer!.cancel();
    }
    print("curIndex = ${_curIndex.value}");

    int jumpIndex = -1;
    if (_curIndex.value > -1) {
      jumpIndex = _curIndex.value + 1;
    } else {
      jumpIndex = _lastIndex + 1;
    }
    if (jumpIndex >= _srts.length) {
      jumpIndex = _srts.length - 1;
    }
    print("跳转${jumpIndex}");
    if (jumpIndex != _srts!.length) {
      print("跳转${_srts![jumpIndex].startTime}");
      _player.seek(Duration(milliseconds: _srts![jumpIndex].startTime));
      _lastJumpTime = DateTime.now();
      _player.play();
    }
    _showSubtitle1.value = false;
  }

  // 跳转
  op_jumpTo(i) {
    _player.pause();
    _jumpingBack = false;
    if (_jumpTimer != null && _jumpTimer!.isActive) {
      _jumpTimer!.cancel();
    }
    _player.seek(Duration(milliseconds: _srts![i].startTime));
    _lastJumpTime = DateTime.now();
    _player.play();
  }

  // 忽略
  op_ignoreSrt() {
    if (_curIndex.value > -1) {
      _srtsOkMap.value[_curIndex.value] = 1;
      // 忽略当前一句
      ModelUserAlbumMediaRecord r = new ModelUserAlbumMediaRecord();
      r.albumId = widget.media.userAlbumId;
      r.mediaId = widget.media.id;
      r.sentenceId = _curIndex.value;
      ModelSrtSpan span = _srts[_curIndex.value];
      r.sentence = span.content; // ?
      r.startTime = span.startTime; // ?
      r.endTime = span.endTime;
      ServiceUserAlbumMediaRecord.saveIgnore(r);

      _showSubtitle1.value = false;
    }
  }

  // 修改字幕
  op_changeSrt() {
    if (_srts != null && _srts.length > 0 && _curIndex.value != -1) {
      _srts[_curIndex.value].content = _srtTextController!.text;
    }
  }

  op_saveRightSentence() {
    ModelUserAlbumMediaRecord r = new ModelUserAlbumMediaRecord();
    r.albumId = widget.media.userAlbumId;
    r.mediaId = widget.media.id;
    r.sentenceId = _curIndex.value;
    ModelSrtSpan span = _srts[_curIndex.value];
    r.sentence = span.content; // ?
    r.startTime = span.startTime; // ?
    r.endTime = span.endTime; // ?
    // r.status = 1;
    ServiceUserAlbumMediaRecord.saveRight(r);
  }

  op_saveWrongSentence() {
    if (_curIndex.value > -1 && _curIndex.value < _srts.length) {
      ModelUserAlbumMediaRecord r = new ModelUserAlbumMediaRecord();
      r.albumId = widget.media.userAlbumId;
      r.mediaId = widget.media.id;
      r.sentenceId = _curIndex.value;
      ModelSrtSpan span = _srts[_curIndex.value];
      r.sentence = span.content; // ?
      r.startTime = span.startTime; // ?
      r.endTime = span.endTime; // ?
      // r.status = -1;
      ServiceUserAlbumMediaRecord.saveWrong(r, _inputWords.value);
    }
  }

  void op_scrollLeft() {
    double p = _scrollController.offset;
    p -= 200;
    if (p < 0) {
      p = 0;
    }
    _scrollController.animateTo(p, duration: Duration(milliseconds: 300), curve: Curves.easeOut);
  }

  void op_scrollRight() {
    double p = _scrollController.offset;
    p += 200;
    if (p < 0) {
      p = 0;
    }
    _scrollController.animateTo(p, duration: Duration(milliseconds: 300), curve: Curves.easeOut);
  }

  //------------------------------------------------------------
  // 停止跳转
  foo_cancelJump() {
    _jumpingBack = false;
    if (_jumpTimer != null && _jumpTimer!.isActive) {
      _jumpTimer!.cancel();
    }
    _jumpingBlank = false;
  }

  // 读取字幕
  Future<void> foo_readSrt() async {
    // 读取字幕文件内容
    if (_srtPath1 == null) {
      print("srt路径字符串不存在,无法读取字幕!");
      return;
    }
    File file = File(_srtPath1!);
    if (!await file.exists()) {
      print("srt路径不存在,无法读取字幕!");
      return;
    }

    String content = file.readAsStringSync();
    print('读取到字幕1:' + content);
    _srts = ToolsSubtitle.handleSrtContent(content);

    // 查询数据库中完成情况
    List<ModelUserAlbumMediaRecord> records =
        await DaoUserAlbumMediaRecord.findAllByMediaId(widget.media.userAlbumId!, widget.media.id!);
    print(records);
    if (_srts != null && _srts.length > 0) {
      for (int i = 0; i < _srts.length; i++) {
        for (int j = 0; j < records.length; j++) {
          ModelUserAlbumMediaRecord r = records[j];
          if (r.sentenceId == i) {
            if (r.status == 1) {
              _srtsOkMap.value[i] = 1;
            } else if (r.status == 0) {
              if (!await r.needReview()) {
                _srtsOkMap.value[i] = 1;
                print("不需要复习");
              }
              // _srtsOkMap[i] = r.needReview() ? 0 : 1;
            } else if (r.status == -2) {
              _srtsOkMap.value[i] = 1;
            }
          }
        }
      }
    }
  }

  // 播放
  foo_play() async {
    if (_mp4Path == null) {
      print("媒体路径字符串不存在,无法读取字幕!");
      ToolsCommon.message(context, "错误", "媒体路径字符串不存在,无法读取字幕!请重新选择专辑文件夹", () {});
      return;
    }
    File file = File(_srtPath1!);
    if (!await file.exists()) {
      print("媒体路径不存在,无法读取字幕!");
      ToolsCommon.message(context, "错误", "媒体路径不存在,无法读取字幕!请重新选择专辑文件夹", () {});
      return;
    }
    _player.open(Media(_mp4Path!));
  }

  static int _listenHandleInterval = 0;
  // 监听处理
  foo_positionListenHandle(Duration position) {
    // 1. 跳转停顿过程中不刷新字幕
    if (_jumpingBack == true) return; // 正在跳回
    if (_jumpingBlank == true) return; // 正在跳空

    // _listenHandleInterval++;
    // if (_listenHandleInterval > 10) {
    //   _listenHandleInterval = 0;
    //   return;
    // }

    // 2. 根据当前播放进度刷新字幕内容
    _playPosition.value = position.inMicroseconds ~/ 1000;
    _playPositionStr.value = ToolsSubtitle.toHHmms(position.inMicroseconds ~/ 1000);
    foo_findSubtitles(position.inMilliseconds);

    // 3. 自动跳转处理

    // 刚jump过，不跳转
    if (_lastJumpTime != null) {
      int timeSpan = DateTime.now().millisecondsSinceEpoch - _lastJumpTime!.millisecondsSinceEpoch;
      if (timeSpan < 500) {
        return;
      }
    }

    if (!_repeatOn.value) return;

    if (_curIndex.value != -1) {
      ModelSrtSpan ss = _srts![_curIndex.value];
      // print("_srtsOkMap[_curIndex.value] =${_srtsOkMap[_curIndex.value]}");
      if (_srtsOkMap.value[_curIndex.value] == null && (position.inMilliseconds - ss.endTime).abs() < 100) {
        _player.pause();
        _jumpToIndex = _curIndex.value;
        foo_repeatOrConinue();
      }
    } else {
      if (_jumpBlank.value) {
        _jumpingBlank = true;
        _player.pause();
        op_nextSrt();
        Future.delayed(Duration(milliseconds: 500), () {
          _jumpingBlank = false;
        });
      }
    }
  }

  // 查找字幕
  foo_findSubtitles(int curTime) {
    // 1. 字幕还没加载完成,直接退出s
    if (_srts == null) return;

    int tmpIndex = -1;
    String tmpSubTitle = "";

    // 还没加载过任何字幕，从头开始找
    int startFind = 0;

    // 加载过，先判断是否在之前范围内
    if (_lastIndex != -1) {
      ModelSrtSpan ss = _srts![_lastIndex];
      if (ss.startTime <= curTime) {
        if (ss.endTime >= curTime) {
          // 在范围内
          startFind = _lastIndex;
        } else {
          // 往后找
          startFind = _curIndex.value + 1;
        }
      } else {
        // 从头找
        startFind = 0;
      }
    }

    for (int i = startFind; i < _srts!.length; i++) {
      ModelSrtSpan ss = _srts![i];
      if (ss.startTime <= curTime) {
        if (ss.endTime >= curTime) {
          // 在范围内
          tmpIndex = i;
          tmpSubTitle = ss.content;
          _lastIndex = i;
          break;
        }
      } else {
        // 结束查找
        break;
      }
    }
    // print("${tmpIndex}:${tmpSubTitle}");
    if (_curIndex.value != tmpIndex) {
      _curIndex.value = tmpIndex;
      _curSubtitle1.value = tmpSubTitle;
      print("${_curIndex.value}:${_curSubtitle1}");
      _curSubtitleWords = ToolsSubtitle.strToWords(_curSubtitle1.value);
      _inputWords.value.clear();
      print(_curSubtitleWords);
    }
    // print("当前字幕:${curIndex},${curSubtitle1}");
  }

  void foo_repeatOrConinue() {
    ModelSrtSpan srt = _srts![_jumpToIndex];
    // print("隔${_repeatWaitTime}秒跳转到${srt.startTime}");
    _jumpingBack = true;

    _jumpTimer = Timer(Duration(milliseconds: _repeatWaitTime * 1000), () {
      // 如果已完成，则继续播放，如果未完成，则跳回
      if (_jumpingBack && _playOn.value) {
        if (_srtsOkMap.value[_jumpToIndex] == null) {
          // 如果还没有完成，则跳回
          _player.seek(Duration(milliseconds: srt.startTime + 3));
          _lastJumpTime = DateTime.now();
        }
        _player.play();
        _jumpingBack = false;
      }
      _jumpTimer!.cancel();
    });
  }

  // 检测输入内容是否正确
  foo_checkInputSubtitle() {
    print("checkInputSubtitle() 检测输入!!!");
    print("当前字幕文字:${_curSubtitleWords}");
    // 比较当前输入的inputLine
    // 和当前的完整字幕curSubtitle1
    // 如果符合 则放入inputWords
    if (_curSubtitleWords.contains(_inputLine.toLowerCase())) {
      print("符合,放入！");
      _inputWords.value.add(_inputLine.value);
      print("当前输入内容:${_inputWords}");

      List<bool> checkList = [];
      List<bool> usedList = [];
      for (int j = 0; j < _inputWords.value.length; j++) {
        usedList.add(false);
      }

      for (int i = 0; i < _curSubtitleWords.length; i++) {
        checkList.add(false);
        for (int j = 0; j < _inputWords.value.length; j++) {
          if (usedList[j] == false && _curSubtitleWords[i].toLowerCase() == _inputWords.value[j].toLowerCase()) {
            checkList[i] = true;
            usedList[j] = true;
            break;
          }
        }
      }
      bool ok = true;
      for (int i = 0; i < _curSubtitleWords.length; i++) {
        if (checkList[i] == false) {
          ok = false;
        }
      }
      if (ok) {
        _srtsOkMap.value[_curIndex.value] = 1;
        // showToast("太棒了！", context: context);
        op_saveRightSentence();
        _showSubtitle1.value = false;
      }
      // setState(() {});
    }
  }
}
